<script lang="ts" setup>
import type { FileObject } from '@/types/api/public'
import upload from '@/request/upload'
import { useChooseImage, useHideLoading, useLoading, useModal } from '@/utils'
import { to } from 'await-to-js'
import { find, omit } from 'lodash-es'
import mime from 'mime'
import { computed } from 'vue'

const props = defineProps<{
  fileList: FileObject[]
}>()

const fileListComputed = computed(() => props.fileList.map(x => ({
  ...x,
  mimeType: getMimeTypeName(x.fileUrl),
})))

const mimeDict = [
  { prefix: 'image/', cn: '图片', en: 'image' },
  { prefix: 'video/', cn: '视频', en: 'video' },
  { prefix: 'audio/', cn: '音频', en: 'audio' },
  { prefix: 'text/', cn: '文本文件', en: 'text' },
  { prefix: 'application/pdf', cn: 'PDF 文档', en: 'pdf' },
  { prefix: 'application/msword', cn: 'Word 文档', en: 'doc' },
  { prefix: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', cn: 'Word 文档', en: 'doc' },
  { prefix: 'application/vnd.ms-excel', cn: 'Excel 文档', en: 'doc' },
  { prefix: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', cn: 'Excel 文档', en: 'doc' },
  { prefix: 'application/vnd.ms-powerpoint', cn: 'PPT 文档', en: 'doc' },
  { prefix: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', cn: 'PPT 文档', en: 'doc' },
  { prefix: 'application/zip', cn: '压缩包', en: 'zip' },
  { prefix: 'application/vnd.rar', cn: '压缩包', en: 'zip' },
  { prefix: 'application/', cn: '文件', en: 'file' },
  { prefix: 'null', cn: '未知文件', en: 'file' },
]

async function handleChooseFile() {
  let uniRes: string[]
  // #ifdef H5
  uniRes = await (async () => {
    const res = await uni.chooseFile({
      count: 1,
    })
    return res.tempFilePaths as string[]
  })()
  // #endif
  // #ifndef H5
  uniRes = await useChooseImage({ count: 1 })
  // #endif

  useLoading(true)
  const [err, res] = await to(
    upload({ filePath: uniRes[0] }),
  )
  useHideLoading()
  if (err) {
    return
  }

  props.fileList.push(res)
}

async function handleDelFileItem(index: number) {
  const { confirm } = await useModal({
    content: '删除该文件？',
    cancelText: '取消',
    confirmText: '删除',
  })
  if (confirm) {
    props.fileList.splice(index, 1)
  }
}

function getMimeTypeName(url: string) {
  const type = mime.getType(url) ?? 'null'
  const matchedType = find(mimeDict, (v, k) => type?.startsWith(v.prefix))!
  return omit(matchedType, 'prefix')
}
</script>

<template>
  <view class="flex flex-col gap-y-7px">
    <template v-for="(file, i) in fileListComputed" :key="i">
      <view class="h-60px flex gap-x-10px rd-8px bg-gray-50">
        <view class="w-80px flex items-center justify-center overflow-hidden rd-l-8px bg-gray-100 text-34px text-gray-600">
          <image v-if="file.mimeType.en === 'image'" :src="file.fileUrl" class="h-full w-full" mode="aspectFill"></image>
          <template v-else>
            <view v-if="file.mimeType.en === 'video'" class="i-tdesign:film-1"></view>
            <view v-if="file.mimeType.en === 'audio'" class="i-tdesign:file-music"></view>
            <view v-if="file.mimeType.en === 'text'" class="i-tdesign:file-1"></view>
            <view v-if="file.mimeType.en === 'pdf'" class="i-tdesign:file-pdf"></view>
            <view v-if="file.mimeType.en === 'doc'" class="i-tdesign:file-image"></view>
            <view v-if="file.mimeType.en === 'zip'" class="i-tdesign:folder-zip text-32px"></view>
            <view v-if="file.mimeType.en === 'file'" class="i-tdesign:file-unknown"></view>
          </template>
        </view>
        <view class="flex-1 truncate text-24px lh-60px">{{ file.fileName || '?' }}</view>
        <view class="text-24px text-gray-400 lh-60px">{{ file.mimeType.cn }}</view>
        <view class="h-60px w-60px flex" @click="handleDelFileItem(i)">
          <view class="i-tdesign:close m-a text-30px text-[red]"></view>
        </view>
      </view>
    </template>
    <view class="h-60px flex items-center justify-center b-2px b-gray-400 rd-8px b-dashed text-gray-400" @click="handleChooseFile">
      <div class="i-fluent:add-circle-24-regular text-26px"></div>
      <view class="ml-10px text-24px">添加图片/视频/文件</view>
    </view>
  </view>
</template>

<style lang="less" scoped></style>
